package com.hns.can.base.service;

import java.util.*;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.hns.can.base.entity.SysAuthrityFieldEntity;
import com.hns.can.base.entity.SysAuthrityFieldValueEntity;
import com.hns.can.base.entity.SysFieldRegisterEntity;
import com.hns.can.base.entity.SysRoleEntity;
import com.hns.can.base.entity.SysUserEntity;
import com.hns.can.base.entity.SysUserRoleEntity;
import com.hns.can.base.vo.UserRoleVo;
import com.hns.can.common.constants.GlobalConst;
import com.hns.can.common.entity.BaseEntity;
import com.hns.can.common.formula.FillCodeDscValue;
import com.hns.can.common.formula.FillParamsVo;
import com.hns.frame.enumrate.MsgType;
import com.hns.frame.exception.BusinessException;
import com.hns.frame.mybatis.Pagination;
import com.hns.frame.service.CommonService;
import com.hns.tool.pub.DataConvertUtil;
import com.hns.tool.pub.PubUtil;
import com.hns.tool.pub.UtilString;

/**
 * 角色信息service
 * @author:zhangyu
 * @email:zhangyu2222z@sina.cn
 * @version Revision 2.0.0
 */
@Service
public class SysRoleService extends CommonService{
    
    @Autowired
    private FillCodeDscValue codeDscValue;
	/**
	 * 用户信息service
	 */
    @Autowired
    private SysUserService sysUserService;
    
    /**
     * 获取所有角色
     * @return 角色信息
     * @author:zhangyu
     * @email:zhangyu2222z@sina.cn
     */
    public List<SysRoleEntity> findAll() {
        return commonEntityDao.findAll(SysRoleEntity.class);
    }
    
    /**
     * 添加角色
     * @param entity 角色信息
     * @author:zhangyu
     * @email:zhangyu2222z@sina.cn
     */
    @CacheEvict(value=GlobalConst.CACHE_KEY_SYS_ROLE, key="#entity.getCorpId()")
    @Transactional
    public void saveSysRole(SysRoleEntity entity){
        //设置时间
    	Date date = new Date();
        entity.setCreateTs(date);
        //编辑角色信息
        commonEntityDao.save(entity);
        
//        List<SysFieldRegisterEntity> list = PubUtil.convertListMapToObject(this.sqlMapDao.selectList("sysRole.getFieldInfo"), SysFieldRegisterEntity.class);
        List<SysFieldRegisterEntity> list = commonEntityDao.findAll(SysFieldRegisterEntity.class);
        for(int i=0;i<list.size();i++){
        	SysAuthrityFieldEntity sysAuthrityFieldEntity = new SysAuthrityFieldEntity();
        	sysAuthrityFieldEntity.setId(UtilString.getUUID());
        	sysAuthrityFieldEntity.setRoleId(entity.getId());
        	sysAuthrityFieldEntity.setFieldId(list.get(i).getId());
        	sysAuthrityFieldEntity.setCreateTs(date);
        	commonEntityDao.save(sysAuthrityFieldEntity);
        }
        
        
        
    }
    
    /**
     * 编辑角色
     * @param entity 角色信息
     * @param userIds 用户id
     * @param set_role
     * @author:zhangyu
     * @email:zhangyu2222z@sina.cn
     */
    @CacheEvict(value=GlobalConst.CACHE_KEY_SYS_ROLE, key="#entity.getCorpId()")
    @Transactional
    public void updateSysRole(SysRoleEntity entity, String[] userIds, Set<SysRoleEntity> set_role) throws Exception{
        HashMap map = new HashMap();
        map.put("roleSet", set_role);
        List<SysRoleEntity> list = PubUtil.convertListMapToObject(this.sqlMapDao.selectList("sysRole.checkSameParentRole", map), SysRoleEntity.class);
        if(PubUtil.isNotEmpty(list)){
            for(int i=0;i<list.size();i++){
                String parentRoleId = list.get(i).getParentRoleId();
                if(PubUtil.isNotEmpty(parentRoleId) && parentRoleId.equals(entity.getId())){
                    throw new BusinessException(MsgType.ERROR.getFlag(), "不能修改您的上级角色!");
                }
            }
        }
//        Iterator<SysRoleEntity> iterator = set_role.iterator();
//        while (iterator.hasNext()){
//            SysRoleEntity role = iterator.next();
//            if(role.getParentRoleId().equals(entity.getId())){
//                throw new BusinessException(MsgType.ERROR.getFlag(), "不能修改您的上级角色!");
//            }
//        }
        //设置更新时间
        entity.setCreateTs(new Date());
        //编辑角色信息
        commonEntityDao.update(entity);
    }
    
    /**
     * 删除角色
     * @param current_user_id 当前用户id
     * @param ids 角色id
     * @throws Exception
     * @author:zhangyu
     * @email:zhangyu2222z@sina.cn
     */
    @CacheEvict(value=GlobalConst.CACHE_KEY_SYS_ROLE, key="#user.getCorpId()")
    @Transactional
    public void deleteSysRole(SysUserEntity user, String[] ids) throws Exception {
        HashMap<String, Object> paramMap=new HashMap<String, Object>();
        paramMap.put("roleId", ids[0]);
        
        // 不能删除自身的角色
        List<SysUserRoleEntity> list = sysUserService.getRoleIdsByUserId(user.getId());
        for(SysUserRoleEntity entity : list){
            if(ids[0].equals(entity.getRoleId())){
                throw new BusinessException(MsgType.WARN.getFlag(), "对不起，您不能删除自身的角色");
            }
        }
        
        //删除该角色对应用户关系
        //1:判断该角色下是否分配用户
        List<SysUserRoleEntity> list1 = commonEntityDao.findByParamsIgnoreNullValue(SysUserRoleEntity.class, paramMap);
        if(list1.size()>0){
//            throw new BusinessException(MsgType.WARN.getFlag(), "该角色已分配用户，不能删除！");
            commonEntityDao.deleteByParamsIgnoreNullValue(SysUserRoleEntity.class, paramMap);
        }
        
        //2:判断该角色下是否存在下级角色
        Integer count = (Integer) sqlMapDao.selectOne("sysRole.getChildRoleCount", paramMap);
        if(count > 0){
            throw new BusinessException(MsgType.WARN.getFlag(), "该角色存在下级角色，不能删除！");
        }
        
        //删除角色对应资源权限
        commonEntityDao.deleteByParamsIgnoreNullValue(SysAuthrityFieldValueEntity.class, paramMap);
        //删除角色信息
        commonEntityDao.delete(SysRoleEntity.class, ids);
        //#upt by jeffxu(字段权限) 删除分配给该角色的字段权限
        commonEntityDao.deleteByParamsIgnoreNullValue(SysAuthrityFieldEntity.class, paramMap);
    }

    
    /**
     * 根据id获取 角色
     * @param userId 用户id
     * @return 角色信息
     * @author:zhangyu
     * @email:zhangyu2222z@sina.cn
     */
    @SuppressWarnings("unchecked")
    public List<SysRoleEntity> getSysRoleListByUserId(String userId) {
        SysUserEntity entity = new SysUserEntity();
        entity.setId(userId);
        List<SysRoleEntity> list = PubUtil.convertListMapToObject(sqlMapDao.selectList("sysRole.getSysRoleListByUserId", entity), SysRoleEntity.class);
        return list;
    }

    /**
     * 通过角色名获取角色
     * @param roleName 角色名称
     * @param corpId 公司id
     * @param userId 用户id
     * @return 角色信息
     * @author:zhangyu
     * @email:zhangyu2222z@sina.cn
     */
    @SuppressWarnings("unchecked")
    public List<BaseEntity> getSysRoleByName(String roleName,String corpId,String userId, String roleType) throws Exception {
        HashMap<String, String> paramMap=new HashMap<String, String>();
        paramMap.put("name", roleName);
	 	paramMap.put("corpId", corpId);
	 	paramMap.put("userId", userId);
        paramMap.put("roleType", roleType);
        List<BaseEntity> list = PubUtil.convertListMapToObject(sqlMapDao.selectList("sysRole.getSysRoleByName", paramMap), SysRoleEntity.class);
        
//        Map<String,String> map = new HashMap<String,String>();
//        map.put("corpName", GlobalConst.DEFAULT_CACHE_VALUE);
//        FillParamsVo vo = new FillParamsVo("corpId", map);
//        codeDscValue.fillInfoValue(list,new String[] {GlobalConst.CACHE_KEY_SYS_CORP}, vo);
        return list;
    }

    /**
     * 通过角色获取对应用户
     * @param roleId 角色id
     * @return 用户信息
     * @author:zhangyu
     * @email:zhangyu2222z@sina.cn
     */
    @SuppressWarnings({"unchecked" })
    public List<SysUserEntity> getUserByRole(String roleId) {
        List<SysUserEntity> list = PubUtil.convertListMapToObject(sqlMapDao.selectList("sysRole.getUserByRoleId", roleId), SysRoleEntity.class); 
        return list;
    }
    
    /**
     * 获取没有改角色对应的用户
     * @param roleId 角色id
     * @return 用户信息
     * @author:zhangyu
     * @email:zhangyu2222z@sina.cn
     */
    @SuppressWarnings("unchecked")
    public List<SysUserEntity> getUnkownUser(String roleId) {
        List<SysUserEntity> list = PubUtil.convertListMapToObject(sqlMapDao.selectList("sysRole.getUnkownUser", roleId),SysUserEntity.class);
        return list;
    }

    /**
     * 添加用户角色关系
     * @param roleId 角色id
     * @param userIds 用户id
     * @author:zhangyu
     * @email:zhangyu2222z@sina.cn
     */
    @Transactional
    public void saveUserRole(String roleId, String[] userIds) {
        for(String userId:userIds){
            SysUserRoleEntity entity = new SysUserRoleEntity();
            entity.setId(UtilString.getUUID());
            //去空格 设置角色id
            entity.setRoleId(PubUtil.filterNULL(roleId));
            //去空格 设置用户id
            entity.setUserId(PubUtil.filterNULL(userId));
            //添加时间
            entity.setCreateTs(new Date());
            commonEntityDao.save(entity);
        }
    }

    /**
     * 删除指定角色对应的用户关系
     * @param roleId 公司id
     * @param userIds 用户id
     * @author:zhangyu
     * @email:zhangyu2222z@sina.cn
     */
    @SuppressWarnings({"rawtypes", "unchecked" })
    @Transactional
    public void deleteUserRole(String roleId, String[] userIds) {
        //去空
        roleId = PubUtil.filterNULL(roleId);
        SysUserRoleEntity entity = new SysUserRoleEntity();
        entity.setRoleId(roleId);
        for(String userId:userIds){
            //去空 设置用户id
            entity.setUserId(PubUtil.filterNULL(userId));
            Map map = DataConvertUtil.ConvertObjToMap(entity);
            commonEntityDao.deleteByParamsIgnoreNullValue(SysUserRoleEntity.class, map);
        }
    }

    /**
     * 获取指定角色对应用户分页数据
     * @param vo 查询参数
     * @return 用户信息
     * @throws QueryExprException
     * @author:zhangyu
     * @email:zhangyu2222z@sina.cn
     */
    public Pagination getPageSysUserEntityList(UserRoleVo vo) throws Exception {
        Pagination page = this.myBatisPage("sysRole.getUserCountByUserRoleVo", "sysRole.getUserListByUserRoleVo", vo, SysUserEntity.class);
        List list = page.getData();
        HashMap map = new HashMap();
        map.put("organName", GlobalConst.DEFAULT_CACHE_VALUE);
        FillParamsVo vo1 = new FillParamsVo("organId", map);
        codeDscValue.fillInfoValue(list, new String[]{GlobalConst.CACHE_KEY_BASE_ORGAN}, vo1);
        page.setData(list);
        return page;
    }
    
    /**
     * 获取指定角色未对应的用户分页数据
     * @param vo 用户角色vo
     * @param curUser 当前用户
     * @return 未对应的用户数据
     * @throws QueryExprException
     * @author:zhangyu
     * @email:zhangyu2222z@sina.cn
     */
    public Pagination getPageUnknowUserList(UserRoleVo vo, SysUserEntity curUser) throws Exception {
    	Map<String,String> paramMap = new HashMap<String,String>();
    	paramMap.put("corpId", vo.getCorpId());
    	paramMap.put("roleId", vo.getRoleId());
    	paramMap.put("acctName", vo.getAcctName());
    	paramMap.put("organId", curUser.getOrganId());
    	
        Pagination page = this.myBatisPage("sysRole.getUnknowUserCountByUserRoleVo", "sysRole.getUnkownUserByUserRoleVo", paramMap, SysUserEntity.class);
        return page;
    }

    /**
     * 校验角色名和角色编码是否重复
     * @param entity 角色信息
     * @param statments 操作语句
     * @return 校验信息
     * @author:zhangyu
     * @email:zhangyu2222z@sina.cn
     */
    public String validateRepeat(SysRoleEntity entity,String statments) {
        StringBuffer error = new StringBuffer("");
        //校验角色编码
        SysRoleEntity roleEntity = new SysRoleEntity();
        //注入需校验信息
        roleEntity.setId(entity.getId());
        roleEntity.setCode(entity.getCode());
        Integer codeRepeat = (Integer)sqlMapDao.selectOne(statments, roleEntity);
        if(codeRepeat > 0)
            error.append("角色编码");
        //校验角色名
        roleEntity = new SysRoleEntity();
        //注入需校验信息
        roleEntity.setId(entity.getId());
        roleEntity.setName(entity.getName());
        Integer nameRepeat = (Integer)sqlMapDao.selectOne(statments, roleEntity);
        if(nameRepeat>0){
            if(codeRepeat > 0){
                error.append("和");
            }
            error.append("角色名");
        }
        return error.toString();
    }
    
}
